home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-03-24 | 42.5 KB | 1,358 lines |
- /* -*-C-*-
- *******************************************************************************
- *
- * File: XFace.m
- * RCS: $Header: /usr/local/lib/cvs/EnhanceMail/XFace.m,v 1.1.1.6 1996/03/25 15:15:04 cedman Exp $
- * Description:
- * Author: Carl Edman
- * Created: Tue Oct 17 08:06:48 1995
- * Modified: Mon Mar 25 09:57:27 1996 (Carl Edman) cedman@capitalist.princeton.edu
- * Language: C
- * Package: N/A
- * Status: Experimental (Do Not Distribute)
- *
- * (C) Copyright 1995, but otherwise this file is perfect freeware.
- *
- *******************************************************************************
- */
-
- #import "XFace.h"
- #import "MailApp.h"
- #import <setjmp.h>
-
- /*
- * Compface - 48x48x1 image compression and decompression
- *
- * Copyright (c) James Ashton - Sydney University - June 1990.
- *
- * Written 11th November 1989.
- *
- * Permission is given to distribute these sources, as long as the
- * copyright messages are not removed, and no monies are exchanged.
- *
- * No responsibility is taken for any errors on inaccuracies inherent
- * either to the comments or the code of this program, but if reported
- * to me, then an attempt will be made to fix them.
- */
-
- #define EMBEDDED
-
- /* need to know how many bits per hexadecimal digit for io */
- #define BITSPERDIG 4
- #ifndef EMBEDDED
- static char HexDigits[]="0123456789ABCDEF";
- #endif
-
- /* define the face size - 48x48x1 */
- #define WIDTH 48
- #define HEIGHT WIDTH
-
- /* total number of pixels and digits */
- #define PIXELS (WIDTH * HEIGHT)
- #define DIGITS (PIXELS / BITSPERDIG)
-
- /* internal face representation - 1 char per pixel is faster */
- static char F[PIXELS];
-
- /* output formatting word lengths and line lengths */
- #define DIGSPERWORD 4
- #define WORDSPERLINE (WIDTH / DIGSPERWORD / BITSPERDIG)
-
- /* compressed output uses the full range of printable characters.
- * in ascii these are in a contiguous block so we just need to know
- * the first and last. The total number of printables is needed too */
- #define FIRSTPRINT '!'
- #define LASTPRINT '~'
- #define NUMPRINTS (LASTPRINT - FIRSTPRINT + 1)
-
- /* output line length for compressed data */
- #define MAXLINELEN 72
-
- /* Portable, very large unsigned integer arithmetic is needed.
- * Implementation uses arrays of WORDs. COMPs must have at least
- * twice as many bits as WORDs to handle intermediate results */
- #define WORD unsigned char
- #define COMP unsigned long
- #define BITSPERWORD 8
- #define WORDCARRY (1 << BITSPERWORD)
- #define WORDMASK (WORDCARRY - 1)
- #define MAXWORDS ((PIXELS * 2 + BITSPERWORD - 1) / BITSPERWORD)
-
- typedef struct bigint
- {
- int b_words;
- WORD b_word[MAXWORDS];
- } BigInt;
-
- static BigInt B;
-
- /* This is the guess the next pixel table. Normally there are 12 neighbour
- * pixels used to give 1<<12 cases but in the upper left corner lesser
- * numbers of neighbours are available, leading to 6231 different guesses */
- typedef struct guesses
- {
- char g_00[1<<12];
- char g_01[1<<7];
- char g_02[1<<2];
- char g_10[1<<9];
- char g_20[1<<6];
- char g_30[1<<8];
- char g_40[1<<10];
- char g_11[1<<5];
- char g_21[1<<3];
- char g_31[1<<5];
- char g_41[1<<6];
- char g_12[1<<1];
- char g_22[1<<0];
- char g_32[1<<2];
- char g_42[1<<2];
- } Guesses;
-
- /* data.h was established by sampling over 1000 faces and icons */
- static Guesses G =
- {
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,
- 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
- 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1,
- 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1,
- 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1,
- 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1,
- 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
- 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1,
- 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
- 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
- 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
- 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
- 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1,
- 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0,
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
- 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
- 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1,
- 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
- 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
- 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0,
- 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0,
- 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1,
- 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
- 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0,
- 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0,
- 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0,
- 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0,
- 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
- 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0,
- 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- },
- {
- 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1,
- 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1,
- 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
- 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- },
- {
- 0, 1, 0, 1,
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
- 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1,
- 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1,
- 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1,
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0,
- 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1,
- 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- },
- {
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,
- },
- {
- 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1,
- 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1,
- 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1,
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0,
- 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1,
- 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1,
- 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1,
- 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1,
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1,
- 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- },
- {
- 0, 0, 0, 1, 0, 1, 1, 1,
- },
- {
- 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1,
- 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- },
- {
- 0, 1,
- },
- {
- 0,
- },
- {
- 0, 0, 0, 1,
- },
- {
- 0, 0, 0, 1,
- }
- };
-
- /* Data of varying probabilities are encoded by a value in the range 0 - 255.
- * The probability of the data determines the range of possible encodings.
- * Offset gives the first possible encoding of the range */
- typedef struct prob
- {
- WORD p_range;
- WORD p_offset;
- } Prob;
-
- /* A stack of probability values */
- static Prob *ProbBuf[PIXELS * 2];
- static int NumProbs=0;
-
- /* Each face is encoded using 9 octrees of 16x16 each. Each level of the
- * trees has varying probabilities of being white, grey or black.
- * The table below is based on sampling many faces */
-
- #define BLACK 0
- #define GREY 1
- #define WHITE 2
-
- static Prob levels[4][3] =
- {
- {{ 1, 255}, {251, 0}, { 4, 251}}, /* Top of tree almost always grey */
- {{ 1, 255}, {200, 0}, { 55, 200}},
- {{ 33, 223}, {159, 0}, { 64, 159}},
- {{131, 0}, { 0, 0}, { 125, 131}} /* Grey disallowed at bottom */
- };
-
- /* At the bottom of the octree 2x2 elements are considered black if any
- * pixel is black. The probabilities below give the distribution of the
- * 16 possible 2x2 patterns. All white is not really a possibility and
- * has a probability range of zero. Again, experimentally derived data */
- static Prob freqs[16] =
- {
- {0, 0}, {38, 0}, {38, 38}, {13, 152}, {38, 76}, {13, 165}, {13, 178},
- {6, 230}, {38, 114}, {13, 191}, {13, 204}, {6, 236}, {13, 217},
- {6, 242}, {5, 248}, {3, 253}
- };
-
- /* successful completion */
- #define ERR_OK 0
- /* completed OK but some input was ignored */
- #define ERR_EXCESS 1
- /* insufficient input. Bad face format? */
- #define ERR_INSUFF -1
- /* Arithmetic overflow or buffer overflow */
- #define ERR_INTERNAL -2
-
- #define GEN(g) F[h] ^= G.g[k]; break
-
- static jmp_buf comp_env;
- #ifndef EMBEDDED
- static int status;
- #endif
-
- static int AllBlack(char *, int, int);
- static int AllWhite(char *, int, int);
- static int BigPop(Prob *);
- static int Same(char *, int, int);
-
- static void BigAdd(unsigned char);
- static void BigClear(void);
- static void BigDiv(unsigned char, unsigned char *);
- static void BigMul(unsigned char);
- static void BigPush(Prob *);
- static void BigRead(const char *);
- static void BigWrite(char *);
- static void CompAll(char *);
- static void Compress(char *, int, int, int);
- static void Gen(char *);
- static void GenFace(void);
- static void PopGreys(char *, int, int);
- static void PushGreys(char *, int, int);
- static void RevPush(Prob *);
- static void UnCompAll(const char *);
- static void UnCompress(char *, int, int, int);
- static void UnGenFace(void);
- #ifndef EMBEDDED
- static void BigPrint(void);
- static void BigSub(unsigned char);
- static void ReadFace(char *);
- static void WriteFace(char *);
- #endif
-
- static void RevPush(Prob *p)
- {
- if (NumProbs >= PIXELS * 2 - 1)
- longjmp(comp_env, ERR_INTERNAL);
- ProbBuf[NumProbs++] = p;
- }
-
- static void BigPush(Prob *p)
- {
- static WORD tmp;
-
- BigDiv(p->p_range, &tmp);
- BigMul(0);
- BigAdd(tmp + p->p_offset);
- }
-
- static int BigPop(Prob *p)
- {
- static WORD tmp;
- int i;
-
- BigDiv(0, &tmp);
- i = 0;
- while ((tmp < p->p_offset) || (tmp >= p->p_range + p->p_offset))
- {
- p++;
- i++;
- }
- BigMul(p->p_range);
- BigAdd(tmp - p->p_offset);
- return i;
- }
-
- #ifndef EMBEDDED
- /* Print a BigInt in HexaDecimal */
- static void BigPrint(void)
- {
- int i, c, count;
- WORD *w;
-
- count = 0;
- w = B.b_word + (i = B.b_words);
- while (i--)
- {
- w--;
- c = *((*w >> 4) + HexDigits);
- putc(c, stderr);
- c = *((*w & 0xf) + HexDigits);
- putc(c, stderr);
- if (++count >= 36)
- {
- putc('\\', stderr);
- putc('\n', stderr);
- count = 0;
- }
- }
- putc('\n', stderr);
- }
- #endif
-
- /* Divide B by a storing the result in B and the remainder in the word
- * pointer to by r */
- static void BigDiv(WORD a, WORD *r)
- {
- int i;
- WORD *w;
- COMP c, d;
-
- a &= WORDMASK;
- if ((a == 1) || (B.b_words == 0))
- {
- *r = 0;
- return;
- }
- if (a == 0) /* treat this as a == WORDCARRY */
- { /* and just shift everything right a WORD */
- i = --B.b_words;
- w = B.b_word;
- *r = *w;
- while (i--)
- {
- *w = *(w + 1);
- w++;
- }
- *w = 0;
- return;
- }
- w = B.b_word + (i = B.b_words);
- c = 0;
- while (i--)
- {
- c <<= BITSPERWORD;
- c += (COMP)*--w;
- d = c / (COMP)a;
- c = c % (COMP)a;
- *w = (WORD)(d & WORDMASK);
- }
- *r = c;
- if (B.b_word[B.b_words - 1] == 0)
- B.b_words--;
- }
-
- /* Multiply a by B storing the result in B */
- static void BigMul(WORD a)
- {
- int i;
- WORD *w;
- COMP c;
-
- a &= WORDMASK;
- if ((a == 1) || (B.b_words == 0))
- return;
- if (a == 0) /* treat this as a == WORDCARRY */
- { /* and just shift everything left a WORD */
- if ((i = B.b_words++) >= MAXWORDS - 1)
- longjmp(comp_env, ERR_INTERNAL);
- w = B.b_word + i;
- while (i--)
- {
- *w = *(w - 1);
- w--;
- }
- *w = 0;
- return;
- }
- i = B.b_words;
- w = B.b_word;
- c = 0;
- while (i--)
- {
- c += (COMP)*w * (COMP)a;
- *(w++) = (WORD)(c & WORDMASK);
- c >>= BITSPERWORD;
- }
- if (c)
- {
- if (B.b_words++ >= MAXWORDS)
- longjmp(comp_env, ERR_INTERNAL);
- *w = (COMP)(c & WORDMASK);
- }
- }
-
- #ifndef EMBEDDED
- /* Subtract a from B storing the result in B */
- static void BigSub(WORD a)
- {
- int i;
- WORD *w;
- COMP c;
-
- a &= WORDMASK;
- if (a == 0)
- return;
- i = 1;
- w = B.b_word;
- c = (COMP)*w - (COMP)a;
- *w = (WORD)(c & WORDMASK);
- while (c & WORDCARRY)
- {
- if (i >= B.b_words)
- longjmp(comp_env, ERR_INTERNAL);
- c = (COMP)*++w - 1;
- *w = (WORD)(c & WORDMASK);
- i++;
- }
- if ((i == B.b_words) && (*w == 0) && (i > 0))
- B.b_words--;
- }
- #endif
-
- /* Add to a to B storing the result in B */
- static void BigAdd(WORD a)
- {
- int i;
- WORD *w;
- COMP c;
-
- a &= WORDMASK;
- if (a == 0)
- return;
- i = 0;
- w = B.b_word;
- c = a;
- while ((i < B.b_words) && c)
- {
- c += (COMP)*w;
- *w++ = (WORD)(c & WORDMASK);
- c >>= BITSPERWORD;
- i++;
- }
- if ((i == B.b_words) && c)
- {
- if (B.b_words++ >= MAXWORDS)
- longjmp(comp_env, ERR_INTERNAL);
- *w = (COMP)(c & WORDMASK);
- }
- }
-
- static void BigClear(void)
- {
- B.b_words = 0;
- }
-
- static int Same(char *f, int wid, int hei)
- {
- char val, *row;
- int x;
-
- val = *f;
- while (hei--)
- {
- row = f;
- x = wid;
- while (x--)
- if (*(row++) != val)
- return(0);
- f += WIDTH;
- }
- return 1;
- }
-
- static int AllBlack(char *f, int wid, int hei)
- {
- if (wid > 3)
- {
- wid /= 2;
- hei /= 2;
- return (AllBlack(f, wid, hei) && AllBlack(f + wid, wid, hei) &&
- AllBlack(f + WIDTH * hei, wid, hei) &&
- AllBlack(f + WIDTH * hei + wid, wid, hei));
- }
- else
- return (*f || *(f + 1) || *(f + WIDTH) || *(f + WIDTH + 1));
- }
-
- static int AllWhite(char *f, int wid, int hei)
- {
- return ((*f == 0) && Same(f, wid, hei));
- }
-
- static void PopGreys(char *f, int wid, int hei)
- {
- if (wid > 3)
- {
- wid /= 2;
- hei /= 2;
- PopGreys(f, wid, hei);
- PopGreys(f + wid, wid, hei);
- PopGreys(f + WIDTH * hei, wid, hei);
- PopGreys(f + WIDTH * hei + wid, wid, hei);
- }
- else
- {
- wid = BigPop(freqs);
- if (wid & 1)
- *f = 1;
- if (wid & 2)
- *(f + 1) = 1;
- if (wid & 4)
- *(f + WIDTH) = 1;
- if (wid & 8)
- *(f + WIDTH + 1) = 1;
- }
- }
-
- static void PushGreys(char *f, int wid, int hei)
- {
- if (wid > 3)
- {
- wid /= 2;
- hei /= 2;
- PushGreys(f, wid, hei);
- PushGreys(f + wid, wid, hei);
- PushGreys(f + WIDTH * hei, wid, hei);
- PushGreys(f + WIDTH * hei + wid, wid, hei);
- }
- else
- RevPush(freqs + *f + 2 * *(f + 1) + 4 * *(f + WIDTH) +
- 8 * *(f + WIDTH + 1));
- }
-
- static void UnCompress(char *f, int wid, int hei, int lev)
- {
- switch (BigPop(&levels[lev][0]))
- {
- case WHITE :
- return;
- case BLACK :
- PopGreys(f, wid, hei);
- return;
- default :
- wid /= 2;
- hei /= 2;
- lev++;
- UnCompress(f, wid, hei, lev);
- UnCompress(f + wid, wid, hei, lev);
- UnCompress(f + hei * WIDTH, wid, hei, lev);
- UnCompress(f + wid + hei * WIDTH, wid, hei, lev);
- return;
- }
- }
-
- static void Compress(char *f, int wid, int hei, int lev)
- {
- if (AllWhite(f, wid, hei))
- {
- RevPush(&levels[lev][WHITE]);
- return;
- }
- if (AllBlack(f, wid, hei))
- {
- RevPush(&levels[lev][BLACK]);
- PushGreys(f, wid, hei);
- return;
- }
- RevPush(&levels[lev][GREY]);
- wid /= 2;
- hei /= 2;
- lev++;
- Compress(f, wid, hei, lev);
- Compress(f + wid, wid, hei, lev);
- Compress(f + hei * WIDTH, wid, hei, lev);
- Compress(f + wid + hei * WIDTH, wid, hei, lev);
- }
-
- static void UnCompAll(const char *fbuf)
- {
- char *p;
-
- BigClear();
- BigRead(fbuf);
- p = F;
- while (p < F + PIXELS)
- *(p++) = 0;
- UnCompress(F, 16, 16, 0);
- UnCompress(F + 16, 16, 16, 0);
- UnCompress(F + 32, 16, 16, 0);
- UnCompress(F + WIDTH * 16, 16, 16, 0);
- UnCompress(F + WIDTH * 16 + 16, 16, 16, 0);
- UnCompress(F + WIDTH * 16 + 32, 16, 16, 0);
- UnCompress(F + WIDTH * 32, 16, 16, 0);
- UnCompress(F + WIDTH * 32 + 16, 16, 16, 0);
- UnCompress(F + WIDTH * 32 + 32, 16, 16, 0);
- }
-
- static void CompAll(char *fbuf)
- {
- Compress(F, 16, 16, 0);
- Compress(F + 16, 16, 16, 0);
- Compress(F + 32, 16, 16, 0);
- Compress(F + WIDTH * 16, 16, 16, 0);
- Compress(F + WIDTH * 16 + 16, 16, 16, 0);
- Compress(F + WIDTH * 16 + 32, 16, 16, 0);
- Compress(F + WIDTH * 32, 16, 16, 0);
- Compress(F + WIDTH * 32 + 16, 16, 16, 0);
- Compress(F + WIDTH * 32 + 32, 16, 16, 0);
- BigClear();
- while (NumProbs > 0)
- BigPush(ProbBuf[--NumProbs]);
- BigWrite(fbuf);
- }
-
- static void BigRead(const char *fbuf)
- {
- int c;
-
- while ((c=*fbuf++) != '\0')
- {
- if ((c < FIRSTPRINT) || (c > LASTPRINT)) continue;
- BigMul(NUMPRINTS);
- BigAdd((WORD)(c - FIRSTPRINT));
- }
- }
-
- static void BigWrite(char *fbuf)
- {
- static WORD tmp;
- static char buf[DIGITS];
- char *s = buf;
- int pos;
-
- while (B.b_words > 0)
- {
- BigDiv(NUMPRINTS, &tmp);
- *(s++) = tmp + FIRSTPRINT;
- }
-
- pos=0;
- while (s-- > buf)
- {
- *fbuf++=*s;
- pos++;
- if (pos==MAXLINELEN)
- {
- *fbuf++='\n';
- *fbuf++=' ';
- pos=0;
- }
- }
- *fbuf++='\0';
- }
-
- #ifndef EMBEDDED
- static void ReadFace(char *fbuf)
- {
- int c, i;
- char *s, *t;
-
- t = s = fbuf;
- for(i = strlen(s); i > 0; i--)
- {
- c = (int)*(s++);
- if ((c >= '0') && (c <= '9'))
- {
- if (t >= fbuf + DIGITS)
- {
- status = ERR_EXCESS;
- break;
- }
- *(t++) = c - '0';
- }
- else if ((c >= 'A') && (c <= 'F'))
- {
- if (t >= fbuf + DIGITS)
- {
- status = ERR_EXCESS;
- break;
- }
- *(t++) = c - 'A' + 10;
- }
- else if ((c >= 'a') && (c <= 'f'))
- {
- if (t >= fbuf + DIGITS)
- {
- status = ERR_EXCESS;
- break;
- }
- *(t++) = c - 'a' + 10;
- }
- else if (((c == 'x') || (c == 'X')) && (t > fbuf) && (*(t-1) == 0))
- t--;
- }
- if (t < fbuf + DIGITS)
- longjmp(comp_env, ERR_INSUFF);
- s = fbuf;
- t = F;
- c = 1 << (BITSPERDIG - 1);
- while (t < F + PIXELS)
- {
- *(t++) = (*s & c) ? 1 : 0;
- if ((c >>= 1) == 0)
- {
- s++;
- c = 1 << (BITSPERDIG - 1);
- }
- }
- }
-
- static void WriteFace(char *fbuf)
- {
- char *s, *t;
- int i, bits, digits, words;
-
- s = F;
- t = fbuf;
- bits = digits = words = i = 0;
- while (s < F + PIXELS)
- {
- if ((bits == 0) && (digits == 0))
- {
- *(t++) = '0';
- *(t++) = 'x';
- }
- if (*(s++))
- i = i * 2 + 1;
- else
- i *= 2;
- if (++bits == BITSPERDIG)
- {
- *(t++) = *(i + HexDigits);
- bits = i = 0;
- if (++digits == DIGSPERWORD)
- {
- *(t++) = ',';
- digits = 0;
- if (++words == WORDSPERLINE)
- {
- *(t++) = '\n';
- words = 0;
- }
- }
- }
- }
- *(t++) = '\0';
- }
- #endif
-
- static void Gen(char *f)
- {
- int m, l, k, j, i, h;
-
- for (j = 0; j < HEIGHT; j++)
- {
- for (i = 0; i < WIDTH; i++)
- {
- h = i + j * WIDTH;
- k = 0;
- for (l = i - 2; l <= i + 2; l++)
- for (m = j - 2; m <= j; m++)
- {
- if ((l >= i) && (m == j))
- continue;
- if ((l > 0) && (l <= WIDTH) && (m > 0))
- k = *(f + l + m * WIDTH) ? k * 2 + 1 : k * 2;
- }
- switch (i)
- {
- case 1 :
- switch (j)
- {
- case 1 : GEN(g_22);
- case 2 : GEN(g_21);
- default : GEN(g_20);
- }
- break;
- case 2 :
- switch (j)
- {
- case 1 : GEN(g_12);
- case 2 : GEN(g_11);
- default : GEN(g_10);
- }
- break;
- case WIDTH - 1 :
- switch (j)
- {
- case 1 : GEN(g_42);
- case 2 : GEN(g_41);
- default : GEN(g_40);
- }
- break;
- case WIDTH :
- switch (j)
- {
- case 1 : GEN(g_32);
- case 2 : GEN(g_31);
- default : GEN(g_30);
- }
- break;
- default :
- switch (j)
- {
- case 1 : GEN(g_02);
- case 2 : GEN(g_01);
- default : GEN(g_00);
- }
- break;
- }
- }
- }
- }
-
- static void GenFace(void)
- {
- static char new[PIXELS];
- char *f1;
- char *f2;
- int i;
-
- f1 = new;
- f2 = F;
- i = PIXELS;
- while (i-- > 0)
- *(f1++) = *(f2++);
- Gen(new);
- }
-
- static void UnGenFace(void)
- {
- Gen(F);
- }
-
- @implementation NXImage(XFace)
- - initXFace:(const char *)xface size:(const NXSize *)size
- {
- int x,y,avg;
- int basex,basey;
- unsigned char *data;
- NXBitmapImageRep *bitrep;
-
- [self initSize:size];
-
- switch (setjmp(comp_env))
- {
- case ERR_INSUFF: /* insufficient input. Bad face format? */
- [self logError:"Insufficient input decoding X face."];
- return nil;
- case ERR_INTERNAL: /* Arithmetic overflow or buffer overflow */
- [self logError:"Internal error in decoding X face."];
- return nil;
- case ERR_EXCESS: /* completed OK but some input was ignored */
- [self logWarning:"Excessive data in X face string ignored."];
- case ERR_OK: /* successful completion */
- default:
- break;
- }
-
- UnCompAll(xface);
- UnGenFace();
-
- bitrep=[[NXBitmapImageRep alloc] initData:0 pixelsWide:size->width pixelsHigh:size->height bitsPerSample:1 samplesPerPixel:1 hasAlpha:NO isPlanar:YES colorSpace:NX_OneIsBlackColorSpace bytesPerRow:0 bitsPerPixel:0];
- data=[bitrep data];
-
- basex=(size->width-WIDTH)/2;
- basey=(size->height-HEIGHT)/2;
-
- /* This double counts the corners, but that is ok, right ?
- In a heuristic anyway */
- avg=0;
- for(x=0;x<WIDTH;x++) avg += F[0*WIDTH+x] + F[(HEIGHT-1)*WIDTH+x];
- for(y=0;y<HEIGHT;y++) avg += F[y*WIDTH+0] + F[y*WIDTH+(WIDTH-1)];
- avg=(avg > (WIDTH+HEIGHT));
-
- for(y=0;y<size->height;y++) for(x=0;x<size->width;x++)
- {
- int pos=x+y*size->width;
-
- if (((x>=basex) && (x<basex+WIDTH) && (y>=basey) && (y<basey+HEIGHT)) ?
- F[(y-basey)*WIDTH+(x-basex)] : avg)
- data[pos/8] |= 1<<(7-pos%8);
- else
- data[pos/8] &= ~(1<<(7-pos%8));
- }
-
- if (![self useRepresentation:bitrep])
- {
- bitrep=[bitrep free];
- return nil;
- }
-
- return self;
- }
-
- - initXFace:(const char *)xface
- {
- NXSize s;
- s.width=WIDTH;
- s.height=HEIGHT;
- return [self initXFace:xface size:&s];
- }
-
- - (char *)xFace
- {
- id list=[self representationList];
- int x,y;
- char *face;
- NXBitmapImageRep *bitrep=nil;
- int bpp=0,width=0,height=0;
- unsigned char *data=0;
- NXColorSpace space=NX_CustomColorSpace;
-
- for(x=[list count]-1;x>=0;x--)
- {
- bitrep=[list objectAt:x];
-
- if (bitrep==nil) continue;
- if (![bitrep isKindOf:[NXBitmapImageRep class]]) continue;
-
- space=[bitrep colorSpace];
- bpp=[bitrep bitsPerPixel];
- data=[bitrep data];
- width=[bitrep pixelsWide];
- height=[bitrep pixelsHigh];
-
- if (((space==NX_OneIsBlackColorSpace)||(space==NX_OneIsWhiteColorSpace))
- && (width==WIDTH) && (height==HEIGHT))
- break;
- else
- bitrep=nil;
- }
-
- if (bitrep==nil)
- {
- [self logWarning:"No valid X face representation in image."];
- return 0;
- }
-
- for(y=0;y<HEIGHT;y++) for(x=0;x<WIDTH;x++)
- {
- int pos=(x+y*width)*bpp;
-
- F[x+y*WIDTH]=(data[pos/8]>>(7-pos%8))&1;
- if (space==NX_OneIsWhiteColorSpace)
- F[x+y*WIDTH]=!F[x+y*WIDTH];
- }
-
- switch (setjmp(comp_env))
- {
- case ERR_INSUFF: /* insufficient input. Bad face format? */
- [self logError:"Insufficient input encoding X face."];
- return 0;
- case ERR_INTERNAL: /* Arithmetic overflow or buffer overflow */
- [self logError:"Internal error in encoding X face."];
- return 0;
- case ERR_EXCESS: /* completed OK but some input was ignored */
- [self logWarning:"Excessive data in X face string ignored."];
- case ERR_OK: /* successful completion */
- default:
- break;
- }
-
- GenFace();
- face=malloc(DIGITS+DIGITS/MAXLINELEN*2+1);
- CompAll(face);
- return face;
- }
-
- - initFromFile:(const char *)filename xFaceSize:(const NXSize *)s
- {
- id image;
- char *face;
-
- image=[[NXImage alloc] init];
- if (image==nil) return [self free];
- if ([image loadFromFile:filename]==NO) return [image free],[self free];
- face=[image xFace];
- image=[image free];
- if (face==0) return [self free];
- image=[self initXFace:face size:s];
- free(face);
- return image;
- }
- @end
-